package goods

import (
	"context"
	"database/sql"
	"errors"
	"video-api/internal/dao"
	"video-api/internal/model/entity"
	"video-api/internal/model/input"
	"video-api/internal/model/out"
	"video-api/internal/service"
	"video-api/utility"

	"github.com/gogf/gf/v2/frame/g"
)

func init() {
	service.RegisterGoodsService(&goodsService{})
}

type goodsService struct{}

func (s *goodsService) GetGoodsInfoById(ctx context.Context, param *input.GoodsDetail) (*out.Goods, error) {
	goodsModel := dao.Goods.Ctx(ctx)
	goods := new(out.Goods)
	//err := goodsModel.Where("id = ?", param.GoodsId).Scan(goods)
	ele, err := goodsModel.One("id = ?", param.GoodsId)
	if err != nil {
		g.Log().Error(ctx, "goodsService-GetGoodsInfoById err：", err, g.Map{"id": param.GoodsId})
		return nil, err
	}
	if ele != nil {
		if err = ele.Struct(goods); err != nil {
			g.Log().Error(ctx, "goodsService-Struct err：", err)
			return nil, err
		}
	}
	// 获取商品价格
	goodsSkuModel := dao.GoodsSku.Ctx(ctx)
	goodsSku := new(entity.GoodsSku)
	err = goodsSkuModel.Where("id = ?", goods.SkuId).Scan(goodsSku)
	if err != nil {
		g.Log().Error(ctx, "goodsService-getGoodsSku err：", err)
	}
	goods.Price = goodsSku.Price
	return goods, nil
}

func (s *goodsService) GetGoodsList(ctx context.Context, param *input.GoodsList) ([]*out.Goods, int, error) {
	// 查找产品id
	product := new(entity.Product)
	productModel := dao.Product.Ctx(ctx)
	if param.DeviceType != "" {
		productModel = productModel.Where("product_device_type = ?", param.DeviceType)
	}
	err := productModel.Scan(&product)
	if err != nil && errors.Is(err, sql.ErrNoRows) {
		return nil, 0, err
	}
	// 查询可用的模板
	goodsTmpModel := dao.GoodsTmp.Ctx(ctx)
	goodsTmp := new(entity.GoodsTmp)
	err = goodsTmpModel.Where("product_id = ? AND enable = 1 AND language_id = ?", product.Id, param.Language).Scan(&goodsTmp)
	if err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return nil, 0, errors.New("产品没有可用的充值模板")
		} else {
			return nil, 0, err
		}
	}
	// 根据模板id查询对应的商品
	goodsTmpInfoModel := dao.GoodsTmpInfo.Ctx(ctx)
	goodsTmpInfos := make([]entity.GoodsTmpInfo, 0)
	err = goodsTmpInfoModel.Where("goods_tmp_id = ?", goodsTmp.Id).Scan(&goodsTmpInfos)
	if err != nil {
		return nil, 0, err
	}

	// 获取商品信息
	goodsIds := make([]int64, len(goodsTmpInfos))
	for i := 0; i < len(goodsTmpInfos); i++ {
		goodsIds[i] = goodsTmpInfos[i].GoodsId
	}
	goodsIds = utility.DeDuplicateSlice(goodsIds)
	goodsModel := dao.Goods.Ctx(ctx)
	goodsModel = goodsModel.Where("enable = 1")
	goodsList := make([]*out.Goods, 0)
	goodsModel = goodsModel.WhereIn("id", goodsIds)
	if len(param.SearchString) != 0 {
		goodsModel = goodsModel.WhereLike("name", "%"+param.SearchString+"%")
	}
	var count int
	if param.Page != 0 && param.PageSize != 0 {
		err = goodsModel.Page(param.Page, param.PageSize).ScanAndCount(&goodsList, &count, true)
	} else {
		err = goodsModel.Page(param.Page, param.PageSize).Scan(&goodsList)
	}
	if err != nil {
		g.Log().Error(ctx, "goodsService-Page err: ", err, g.Map{"page": param.Page, "pageSize": param.PageSize})
		return nil, 0, err
	}
	// 获取商品Sku信息
	goodsSkuIds := make([]int64, len(goodsTmpInfos))
	for i, goods := range goodsList {
		goodsSkuIds[i] = goods.SkuId
	}
	goodsSkuIds = utility.DeDuplicateSlice(goodsSkuIds)
	goodsSkuModel := dao.GoodsSku.Ctx(ctx)
	goodsSkus := make([]entity.GoodsSku, 0)
	err = goodsSkuModel.WhereIn("id", goodsSkuIds).Scan(&goodsSkus)
	if err != nil {
		return nil, 0, err
	}
	goodsSkuMap := make(map[int64]entity.GoodsSku)
	for _, goodsSkuEle := range goodsSkus {
		goodsSkuMap[goodsSkuEle.Id] = goodsSkuEle
	}
	for i, goods := range goodsList {
		goodsList[i].Price = goodsSkuMap[goods.SkuId].Price
	}
	return goodsList, count, nil
}

func (s *goodsService) GetGoodsInfoByParam(ctx context.Context, param *input.GoodsDetail) ([]*out.Goods, error) {
	goodsModel := dao.Goods.Ctx(ctx)
	goodsList := make([]*out.Goods, 0)
	if len(param.GoodsIds) > 0 {
		goodsModel = goodsModel.WhereIn("id", param.GoodsIds)
	}
	err := goodsModel.Scan(&goodsList)
	if err != nil {
		return nil, err
	}
	skuIds := make([]int64, len(goodsList))
	for i := 0; i < len(goodsList); i++ {
		skuIds[i] = goodsList[i].SkuId
	}
	skuIds = utility.DeDuplicateSlice(skuIds)
	// 获取商品价格
	goodsSkuModel := dao.GoodsSku.Ctx(ctx)
	goodsSku := make([]entity.GoodsSku, 0)
	err = goodsSkuModel.WhereIn("id", skuIds).Scan(&goodsSku)
	if err != nil {
		g.Log().Error(ctx, "goodsService-GetGoodsInfoByParam-getSku err：", err)
		return nil, err
	}
	for j := 0; j < len(goodsList); j++ {
		for _, sku := range goodsSku {
			if sku.Id == goodsList[j].SkuId {
				goodsList[j].Price = sku.Price
			}
		}
	}
	return goodsList, nil
}
